


#ifndef PF_FILTERDXF_H
#define PF_FILTERDXF_H

#include "pf_filterinterface.h"
#include "lx_Export.h"

#include "pf_block.h"
#include "pf_color.h"
#include "pf_dimension.h"
#include "pf_insert.h"
#include "pf_layer.h"
#include "pf_leader.h"
#include "pf_polyline.h"
#include "pf_solid.h"
#include "pf_text.h"
#include "pf_image.h"

#include "dxf_creationinterface.h"
#include "dxf_lib.h"

class PF_Spline;
class PF_Hatch;
class DXF_WriterA;

/**
 * This format filter class can import and export DXF files.
 * It depends on the dxflib library.
 *

 */
class LX_EXPORT PF_FilterDXF : public PF_FilterInterface, DXF_CreationInterface {
public:
    PF_FilterDXF();
    ~PF_FilterDXF();
	
	/**
	 * @return LX_Define::FormatDXF.
	 */
	//LX_Define::FormatType rtti() {
	//	return LX_Define::FormatDXF;
	//}

	/*
    virtual bool canImport(LX_Define::FormatType t) {
		return (t==LX_Define::FormatDXF);
	}
	
    virtual bool canExport(LX_Define::FormatType t) {
		return (t==LX_Define::FormatDXF || t==LX_Define::FormatDXF12);
	}*/

    // Import:
    virtual bool fileImport(PF_Graphic& g, const QString& file, LX_Define::FormatType /*type*/);

    // Methods from DL_CreationInterface:
    virtual void addLayer(const DXF_LayerAttribute& data);
    virtual void addBlock(const DXF_BlockAttribute& data);
    virtual void endBlock();
    virtual void addPoint(const DXF_PointAttribute& data);
    virtual void addLine(const DXF_LineAttribute& data);
    virtual void addArc(const DXF_ArcAttribute& data);
    virtual void addEllipse(const DXF_EllipseAttribute& data);
    virtual void addCircle(const DXF_CircleAttribute& data);
    virtual void addPolyline(const DXF_PolylineAttribute& data);
    virtual void addVertex(const DXF_VertexAttribute& data);
    virtual void addSpline(const DXF_SplineAttribute& data);
    virtual void addKnot(const DXF_KnotAttribute&) {}
    virtual void addControlPoint(const DXF_ControlPointAttribute& data);
    virtual void addInsert(const DXF_InsertAttribute& data);
    virtual void addTrace(const DXF_TraceAttribute& ) {}
    virtual void addSolid(const DXF_SolidAttribute& ) {}
    virtual void addMTextChunk(const char* text);
    virtual void addMText(const DXF_MTextAttribute& data);
    virtual void addText(const DXF_TextAttribute& data);
    //virtual void addDimension(const DL_DimensionData& data);
    PF_DimensionAttribute convDimensionData(const DXF_DimensionAttribute& data);
    virtual void addDimAlign(const DXF_DimensionAttribute& data,
                             const DXF_DimAlignedAttribute& edata);
    virtual void addDimLinear(const DXF_DimensionAttribute& data,
                              const DXF_DimLinearAttribute& edata);
    virtual void addDimRadial(const DXF_DimensionAttribute& data,
                              const DXF_DimRadialAttribute& edata);
    virtual void addDimDiametric(const DXF_DimensionAttribute& data,
                                 const DXF_DimDiametricAttribute& edata);
    virtual void addDimAngular(const DXF_DimensionAttribute& data,
                               const DXF_DimAngularAttribute& edata);
    virtual void addDimAngular3P(const DXF_DimensionAttribute& data,
                                 const DXF_DimAngular3PAttribute& edata);
    virtual void addLeader(const DXF_LeaderAttribute& data);
    virtual void addLeaderVertex(const DXF_LeaderVertexAttribute& data);
    virtual void addHatch(const DXF_HatchAttribute& data);
    virtual void addHatchLoop(const DXF_HatchLoopAttribute& data);
    virtual void addHatchEdge(const DXF_HatchEdgeAttribute& data);
    virtual void addImage(const DXF_ImageAttribute& data);
    virtual void linkImage(const DXF_ImageDefAttribute& data);
    virtual void endEntity();
    virtual void endSequence() {}

    virtual void add3dFace(const DXF_3dFaceAttribute& data);
    virtual void addDimOrdinate(const DXF_DimensionAttribute&, const DXF_DimOrdinateAttribute&);
    virtual void addComment(const char*);

    virtual void setVariableVector(const char* key,
                                   double v1, double v2, double v3, int code);
    virtual void setVariableString(const char* key, const char* value, int code);
    virtual void setVariableInt(const char* key, int value, int code);
    virtual void setVariableDouble(const char* key, double value, int code);

    // Export:
    virtual bool fileExport(PF_Graphic& g, const QString& file, LX_Define::FormatType type);

    void writeVariables(DXF_WriterA& dw);
    void writeLayer(DXF_WriterA& dw, PF_Layer* l);
    void writeLineType(DXF_WriterA& dw, LX_Define::LineType t);
    void writeAppid(DXF_WriterA& dw, const char* appid);
    void writeBlock(DXF_WriterA& dw, PF_Block* blk);
    void writeEntity(DXF_WriterA& dw, PF_Entity* e);
    void writeEntity(DXF_WriterA& dw, PF_Entity* e, const DXF_Attributes& attrib);
	void writePoint(DXF_WriterA& dw, PF_Point* p, const DXF_Attributes& attrib);
	void writeLine(DXF_WriterA& dw, PF_Line* l, const DXF_Attributes& attrib);
	void writePolyline(DXF_WriterA& dw, 
		PF_Polyline* l, const DXF_Attributes& attrib);
	void writeSpline(DXF_WriterA& dw, 
		PF_Spline* s, const DXF_Attributes& attrib);
	void writeCircle(DXF_WriterA& dw, PF_Circle* c, const DXF_Attributes& attrib);
	void writeArc(DXF_WriterA& dw, PF_Arc* a, const DXF_Attributes& attrib);
	void writeEllipse(DXF_WriterA& dw, PF_Ellipse* s, const DXF_Attributes& attrib);
	void writeInsert(DXF_WriterA& dw, PF_Insert* i, const DXF_Attributes& attrib);
	void writeText(DXF_WriterA& dw, PF_Text* t, const DXF_Attributes& attrib);
	void writeDimension(DXF_WriterA& dw, PF_Dimension* d, 
		const DXF_Attributes& attrib);
	void writeLeader(DXF_WriterA& dw, PF_Leader* l, const DXF_Attributes& attrib);
	void writeHatch(DXF_WriterA& dw, PF_Hatch* h, const DXF_Attributes& attrib);
	void writeSolid(DXF_WriterA& dw, PF_Solid* s, const DXF_Attributes& attrib);
	void writeImage(DXF_WriterA& dw, PF_Image* i, const DXF_Attributes& attrib);
	void writeEntityContainer(DXF_WriterA& dw, PF_Container* con, 
		const DXF_Attributes& attrib);
	void writeAtomicEntities(DXF_WriterA& dw, PF_Container* c, 
		const DXF_Attributes& attrib, LX_Define::ResolveLevel level);
	
    void writeImageDef(DXF_WriterA& dw, PF_Image* i);

    void setEntityAttributes(PF_Entity* entity, const DXF_Attributes& attrib);
    DXF_Attributes getEntityAttributes(PF_Entity* entity);

    static QString toDxfString(const QString& string);
    static QString toNativeString(const char* data, const QString& encoding);
    QString getDXFEncoding();

public:
    PF_Pen attributesToPen(const DXF_Attributes& attrib) const;

    static PF_Color numberToColor(int num, bool comp=false);
    static int colorToNumber(const PF_Color& col);

    static LX_Define::LineType nameToLineType(const QString& name);
    static QString lineTypeToName(LX_Define::LineType lineType);
    //static QString lineTypeToDescription(LX_Define::LineType lineType);

    static LX_Define::LineWidth numberToWidth(int num);
    static int widthToNumber(LX_Define::LineWidth width);

	static LX_Define::AngleFormat numberToAngleFormat(int num);
	static int angleFormatToNumber(LX_Define::AngleFormat af);

	static LX_Define::Unit numberToUnit(int num);
	static int unitToNumber(LX_Define::Unit unit);
	
        static bool isVariableTwoDimensional(const QString& var);

private:
    /** Pointer to the graphic we currently operate on. */
    PF_Graphic* graphic;
	/** File name. Used to find out the full path of images. */
        QString file;
    /** string for concatinating text parts of MTEXT entities. */
    QString mtext;
    /** Pointer to current polyline entity we're adding vertices to. */
    PF_Polyline* polyline;
    /** Pointer to current spline entity we're adding control points to. */
    PF_Spline* spline;
    /** Pointer to current leader entity we're adding vertices to. */
    PF_Leader* leader;
    /** Pointer to current entity container (either block or graphic) */
    PF_Container* currentContainer;

    /** Pointer to current hatch or NULL. */
    PF_Hatch* hatch;
    /** Pointer to current hatch loop or NULL. */
    PF_Container* hatchLoop;

    DXF_Lib dxf;
    PF_VariableDict variables;
}
;

#endif
